#include "io.h"
#include <fcntl.h>
#include "log.h"

int setNonblocking(int fd) {
    int flags;

    /* If they have O_NONBLOCK, use the Posix way to do it */
#if defined(O_NONBLOCK)
    if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
        flags = 0;
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
    /* Otherwise, use the old way of doing it */
    flags = 1;
    return ioctl(fd, FIOBIO, &flags);
#endif
}

ssize_t readLowLevel(int fd, void *buf, size_t count) {
    ssize_t ret;

    while ((ret = read(fd, buf, count)) < 0 && errno == EINTR)
        ;

    return ret;
}

/**
 * return:
 *     On success, the number of bytes written is returned (zero indicates
 *     nothing was written).  On error, -1 is returned, and errno is set
 *     appropriately.
 * errno:
 *     Except EINTR. see write(2).
 */
ssize_t writeLowLevel(int fd, const void *buf, size_t count) {
    ssize_t ret;

    while ((ret = write(fd, buf, count)) < 0 && errno == EINTR)
        ;

    return ret;
}

int connectLowLevel(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
    int ret;

    while ((ret = connect(sockfd, addr, addrlen)) < 0 && errno == EINTR)
        ;

    return ret;
}
